﻿using System;
using System.Configuration;
using YEA.Infrastructure.Gateway;
using YEA.Monitor.LogManager;
using YEA.Utilities.Service.Controller;

namespace YEA.Monitor.LogService.States
{
    public class RunningState : ServiceStateBase, IServiceState 
    {
        public const string LogReceiverKey = "LogReceiverName";
        public string logReceiverName;

        protected IAsyncConsumerProcessor receiver;
        protected MessageHandler mh;
        protected ServiceStatus status;

        public IGatewayFactory GatewayFactory { get; set; }

        protected log4net.ILog _logger;
        public log4net.ILog Logger 
        { 
            get { return _logger; }
            set { _logger = value; }
        }

        private bool disposed;

        public RunningState()
        {
            logReceiverName = ConfigurationManager.AppSettings[LogReceiverKey];
            if (string.IsNullOrEmpty(logReceiverName))
                throw new ConfigurationErrorsException(string.Format("the configuration key {0} is required, please add it to the app setting section of your configuration file", LogReceiverKey));
            status = ServiceStatus.Initiated;
            mh = new MessageHandler();
            disposed = false;
                
        }
        ~RunningState()
        {
            Dispose(false);
        }

        public RunningState(IGatewayFactory gf)
            : this()
        {
            GatewayFactory = gf;
        }

        public void Start()
        {
            try
            {
                if (GatewayFactory == null)
                    GatewayFactory = new GatewayFactory();
                SendStatusEvent( new StateEventArgs{ state = StateEvent.Started });
                receiver = GatewayFactory.GetAsyncReceiver(logReceiverName, mh.ConsumeMessage);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception encountered during gateway processing", ex);
                SendStatusEvent(new StateEventArgs { state = StateEvent.Errored, stateDetails = ex });
            }
        }
        
        public void Stop()
        {
            if (receiver != null)
                receiver.Stop();
            mh.Dispose();
            GatewayFactory.Dispose();
            GatewayFactory = null;
        }

        public void Pause()
        {
            Stop();
        }

        public void Continue()
        {
            Start();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if( receiver != null)
                    receiver.Stop();
                if( GatewayFactory != null)
                    GatewayFactory.Dispose();
                log4net.LogManager.Shutdown();
            }
            receiver = null;
            _logger = null;
            GatewayFactory = null;
            disposed = true;
        }
    }
}
